import {
  shops
} from '../../../tools/shops';
import {
  dsx
} from '../../../tools/datax';
import {
  dateTool
} from '../../../tools/date';
import {
  ui
} from '../../../tools/ui';
import {
  pages
} from '../../../tools/pages';
import {
  resource
} from '../../../static/resource';


const _ = dsx.cmd,
  $ = _.aggregate

Page({
  data: {
    user: {},
    chatUsers: {},
    chatList: [],
    enableRefresher: false,
    defaultAvatar: resource.img.defaultAvatar,
    msgCountList: {},
    loadingMore: true,
    loadAll: false,
    loadRange: 'unread'
  },
  async onLoad(options) {
    this.options = options
    if (options.loadRange) this.setData({
      loadRange: options.loadRange
    })

    this.initData()
    await this.loadUser()
    this.loadContent()
  },
  initData() {
    this.page = 0
    this.pageSize = 10
    this.setData({
      chatUsers: {},
      chatList: [],
      loadingMore: true,
      loadAll: false
    })
  },
  async loadContent() {
    const {
      loadRange
    } = this.data
    if (loadRange == 'unread') {
      await this.loadNewMsgCount()
    }
    this.loadChatList()
  },
  async loadUser() {
    if (this.user) return this.user
    this.user = (await dsx.cloudGetByOpenid('users')).result.data[0]
  },
  async loadShopUsers() {
    if (this.shopUserOpenIds) return this.shopUserOpenIds

    const user = this.user
    if (user.role == 'master') {
      const res = await wx.cloud.callFunction({
        name: 'userCmd',
        data: {
          cmd: 'getShopUsers',
          userId: user._id,
          resultType: 'openid'
        }
      })
      if (res.result?.length > 0) return (this.shopUserOpenIds = res.result)
    }
    return null
  },
  async loadChatList() {
    const {
      chatList,
      msgCountList,
      loadRange
    } = this.data
    const openids = await this.loadShopUsers()
    const unreadOpenIds = Object.keys(msgCountList)

    let sessionOpenId = _
    if (loadRange == 'unread') sessionOpenId = sessionOpenId.in(unreadOpenIds)
    if (openids) sessionOpenId = sessionOpenId.and(_.in(openids))

    dsx.coll('chat')
      .aggregate()
      .match({
        contents: _.elemMatch({
          time: _.exists(true)
        }),
        sessionOpenId: (sessionOpenId == _ ? _.exists(true) : sessionOpenId)
      })
      .project({
        contents: $.slice(['$contents', -1]),
        sessionOpenId: 1
      })
      .sort({
        'contents.0.time': -1
      })
      .skip(this.page * this.pageSize)
      .limit(this.pageSize)
      .end()
      .then(res => {
        const resultList = res.list
        for (const chat of resultList) {
          chat.description = dateTool.readable(chat.contents[0].time)
        }
        this.setData({
          chatList: chatList.concat(resultList),
          loadAll: this.pageSize > resultList.length,
        })
        this.loadingMore(false)
        this.loadChatUsers(resultList)
      })
  },
  async loadChatUsers(chatList) {
    const chatUsers = this.data.chatUsers
    // chat list users
    const openidList = chatList.map(ele => ele.sessionOpenId)
    dsx.coll('users').where({
        _openid: _.in(openidList)
      })
      .field({
        _openid: true,
        role: true,
        personInfo: true
      })
      .get()
      .then(res => {
        for (const user of res.data) chatUsers[user._openid] = user
        this.setData({
          chatUsers,
        })
      })
  },
  loadNewMsgCount() {
    return wx.cloud.callFunction({
      name: 'chatCmd',
      data: {
        cmd: 'peekNewMsg',
        userOpenId: true
      }
    }).then(res => {
      const msgCountList = {}
      let count = 0
      for (const chat of res.result.chatList) {
        msgCountList[chat.sessionOpenId] = Math.min(chat.newMsgCount, 99)
        count += chat.newMsgCount
      }
      this.setData({
        msgCountList
      })
      wx.setNavigationBarTitle({
        title: count > 0 ? `会话列表（${count}未读）` : '会话列表',
      })
    })
  },
  sortChatList(chatList) { // not used
    return chatList.sort((a, b) => {
      const ta = a.contents.slice(-1)[0].time,
        tb = b.contents.slice(-1)[0].time
      return tb - ta
    })
  },
  setNewMsgCount(chat) {
    const readTime = chat.read?.[`${this.user._id}`]
    chat.newMsgCount = 0
    if (!readTime) {
      for (const msg of chat.contents) {
        if (msg.userId != this.user._id) chat.newMsgCount += 1
      }
      return
    }

    const length = chat.contents.length
    for (let index = length - 1; index < length; ++index) {
      const ele = chat.contents[index]
      if (ele.time <= readTime) break
      if (ele.userId == this.user._id) continue
      chat.newMsgCount += 1
      if (chat.newMsgCount > 99) break
    }
  },
  onAvatarTap() {
    const action = this.data.user.role == 'admin' ? 'edit' : 'read'
    wx.navigateTo({
      url: `/pages/usercenter/staff/edit/index?action=${action}`,
    })
  },
  onEnterChatTap(e) {
    const sessionOpenId = ui.eventData(e, 'sessionopenid')
    wx.navigateTo({
      url: `/pages/chat/chat?sessionOpenId=${sessionOpenId}`,
    })
  },
  backFromChatSession() {
    this.onLoad(this.options)
  },
  backTap() {
    pages.back();
  },
  addTap() {
    wx.navigateTo({
      url: './edit/delivery?action=add',
    })
  },
  handleRefresher() {
    this.onLoad()
    this.setData({
      enableRefresher: false
    })
  },
  loadingMore(loading) {
    this.setData({
      loadingMore: typeof (loading) == 'undefined' ? true : loading
    })
  },
  onScrollToBottom(e) {
    // this.loadingMore(true)

  },
  loadMoreTap() {
    this.loadingMore()
    this.page += 1
    this.loadContent()
  },
  allMsgTap() {
    wx.navigateTo({
      url: '/pages/chat/list/chatlist?loadRange=history',
    })
  },
  async delUnreadTap() {
    const {
      chatList,
    } = this.data

    if (!chatList || chatList.length <= 0) return
    const yes = await ui.confirmx('标为已读吗？')
    if (!yes) return

    ui.loading()
    for (const chat of chatList) {
      const lastContent = chat.contents[chat.contents.length - 1]
      const readVal = {}
      readVal[this.user._id] = lastContent.time

      await dsx.cloudUpdate('chat', chat._id, {
        read: readVal
      })
    }
    ui.loading(false)
    this.onLoad(this.options)
  }
})